<script setup>
import { computed, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { useUserStore } from '@/stores/modules/user.js'
import api from '@/api/index.js'

const userStore = useUserStore()
const dicts = computed(() => userStore.dicts)
const emits = defineEmits(['close', 'init', 'reload'])
const props = defineProps({
  curRow: {
    type: Object,
    default: () => ({})
  }
})
// 弹窗标题
const title = computed(() => (props.curRow.id ? '编辑数据' : '新增数据'))
// 表单数据
const formData = ref({
  type: '',
  constLabel: '',
  constValue: ''
})
// 同步表格数据到表单数据内
watch(
  () => props.curRow,
  (val) => {
    formData.value = { ...formData.value, ...val }
  },
  { deep: true, immediate: true }
)
// 是否显示弹窗
const show = ref(false)
// 弹窗显示状态切换时触发
const afterOpenChange = (bool) => {
  if (!bool) {
    formData.value = {
      type: '',
      constLabel: '',
      constValue: ''
    }
    emits('close')
  }
}
// 编辑成功修改缓存
const changeDictFromPinia = (params, newId) => {
  let newDict = dicts.value[params.type]
  let newItem = newDict.find((e) => e.id === params.id)
  if (newItem?.id) {
    newItem.constValue = params.constValue
    newItem.constLabel = params.constLabel
    newDict = newDict.map((e) => (e.id === params.id ? newItem : e))
  } else {
    newDict.push({
      id: newId,
      constValue: params.constValue,
      constLabel: params.constLabel
    })
  }
  const newDicts = { ...dicts.value, [params.type]: newDict }
  userStore.setDicts(newDicts)
}
// 提交按钮loading状态
const submitLoading = ref(false)
// 编辑数据
const emitItem = async (info) => {
  submitLoading.value = true
  const params = { ...formData.value, ...info }
  await api
    .editDict(params)
    .then(() => {
      message.success('编辑成功')
      changeDictFromPinia(params)
      show.value = false
      setTimeout(() => {
        submitLoading.value = false
      }, 30)
      emits('reload')
    })
    .catch(() => {
      setTimeout(() => {
        submitLoading.value = false
      }, 30)
    })
}
// 新增数据
const addItem = async (info) => {
  submitLoading.value = true
  const params = { ...formData.value, ...info }
  await api
    .addDict(params)
    .then((res) => {
      const { data } = res
      message.success('新增成功')
      changeDictFromPinia(params, data)
      show.value = false
      setTimeout(() => {
        submitLoading.value = false
      }, 30)
      emits('reload')
    })
    .catch(() => {
      setTimeout(() => {
        submitLoading.value = false
      }, 30)
    })
}
// 表单提交，验证通过了
const onFinish = (values) => {
  if (formData.value.id) {
    emitItem(values)
  } else {
    addItem(values)
  }
}
// 验证失败
const onFinishFailed = (errorInfo) => {
  console.log('Failed:', errorInfo)
}
// 打开弹窗
const open = () => {
  show.value = true
}
// 表单节点
const formRef = ref()
// 提交表单
const submit = () => {
  formRef.value.validateFields().then(onFinish).catch(onFinishFailed)
}
defineExpose({ open })

const dictList = ref(window.config.dictList)
</script>

<template>
  <a-drawer
    :maskClosable="false"
    :closable="false"
    destroyOnClose
    v-model:open="show"
    class="custom-class"
    root-class-name="root-class-name"
    :title="title"
    placement="right"
    @after-open-change="afterOpenChange"
  >
    <a-form
      ref="formRef"
      :model="formData"
      layout="vertical"
      autocomplete="off"
      @finish="onFinish"
      @finishFailed="onFinishFailed"
    >
      <a-form-item
        label="所属字典"
        name="type"
        :rules="[{ required: true, message: '请选择所属字典' }]"
      >
        <!-- <a-input v-model:value="formData.type" /> -->
        <ASelect
          allowClear
          :options="dictList"
          class="com-ipt"
          v-model:value="formData.type"
          placeholder="请选择所属字典"
        />
      </a-form-item>
      <a-form-item
        label="字典名"
        name="constLabel"
        :rules="[{ required: true, message: '请输入' }]"
      >
        <a-input v-model:value="formData.constLabel" />
      </a-form-item>
      <a-form-item
        label="字典值"
        name="constValue"
        :rules="[{ required: true, message: '请输入' }]"
      >
        <a-input v-model:value="formData.constValue" />
      </a-form-item>
    </a-form>
    <template #footer>
      <div style="display: flex; gap: 5px">
        <a-button type="primary" html-type="submit" @click="submit" :loading="submitLoading"
          >提交</a-button
        >
        <a-button type="primary" ghost @click="show = false">取消</a-button>
      </div>
    </template>
  </a-drawer>
</template>